﻿using LiveCharts;
using LiveCharts.Wpf;
using Microsoft.VisualBasic.Logging;
using MySql.Data.MySqlClient;
using Mysqlx.Crud;
using MySqlX.XDevAPI.Common;
using NewChillers.Helpers;
using NewChillers.Models;
using NewChillers.Models.Events;
using NewChillers.Utils;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace NewChillers.ViewModels
{
    public class ProductViewModel : ObservableObject
    {
        private UserModel _currentUser;
        private readonly ShellViewModel _shellViewModel;
        private List<ProductModel> _productList; // 产品列表
        private bool _isProductListLoading; // 是否加载中
        private DateTime? _startTime; // 开始时间
        private DateTime? _endTime; // 截止时间
        private List<string> _recipeProcessSource; // 工艺流程 下拉框
        private List<string> _processStatusSource; // 加工状态 下拉框
        private List<string> _workstationIdSource; // 生产工位 下拉框
        private string _selectedRecipeProcess;
        private string _selectedProcessStatus;
        private string _selectedWorkstationId;
        private string _txtSearch; // 搜索栏
        private SeriesCollection _seriesCollection; // 柱状图用 系列集合
        private List<string> _labels; // 柱状图用 标签集合

        public List<ProductModel> ProductList
        {
            get => _productList;
            set => SetProperty(ref _productList, value);
        }
        public bool IsProductListLoading
        {
            get => _isProductListLoading;
            set => SetProperty(ref _isProductListLoading, value);
        }
        public DateTime? StartTime
        {
            get => _startTime;
            set => SetProperty(ref _startTime, value);
        }
        public DateTime? EndTime
        {
            get => _endTime;
            set => SetProperty(ref _endTime, value);
        }
        public List<string> RecipeProcessSource
        {
            get => _recipeProcessSource;
            set => SetProperty(ref _recipeProcessSource, value);
        }
        public List<string> ProcessStatusSource
        {
            get => _processStatusSource;
            set => SetProperty(ref _processStatusSource, value);
        }
        public List<string> WorkstationIdSource
        {
            get => _workstationIdSource;
            set => SetProperty(ref _workstationIdSource, value);
        }
        public string SelectedRecipeProcess
        {
            get => _selectedRecipeProcess;
            set => SetProperty(ref _selectedRecipeProcess, value);
        }
        public string SelectedProcessStatus
        {
            get => _selectedProcessStatus;
            set => SetProperty(ref _selectedProcessStatus, value);
        }
        public string SelectedWorkstationId
        {
            get => _selectedWorkstationId;
            set => SetProperty(ref _selectedWorkstationId, value);
        }
        public string TxtSearch
        {
            get => _txtSearch;
            set => SetProperty(ref _txtSearch, value);
        }
        public SeriesCollection SeriesCollection
        {
            get => _seriesCollection;
            set => SetProperty(ref _seriesCollection, value);
        }
        public List<string> Labels
        {
            get => _labels;
            set => SetProperty(ref _labels, value);
        }

        // 选中的天数 7 or 14
        private int _selectedDays = 7;
        public int SelectedDays
        {
            get => _selectedDays;
            set
            {
                _selectedDays = value;
                RaisePropertyChanged();
                LoadChartData();
            }
        }

        // 计划产量
        private int _plannedProduction;
        public int PlannedProduction
        {
            get => _plannedProduction;
            set
            {
                if (SetProperty(ref _plannedProduction, value))
                    RaisePropertyChanged(nameof(CompletionRate));
                    RaisePropertyChanged(nameof(CompletionRateDisplay));
            }
        }
        // 完成产量
        private int _actualProduction;
        public int ActualProduction
        {
            get => _actualProduction;
            set
            {
                if (SetProperty(ref _actualProduction, value))
                    RaisePropertyChanged(nameof(CompletionRate));
                    RaisePropertyChanged(nameof(CompletionRateDisplay));
            }
        }
        // 完成率
        public double CompletionRate
        {
            get
            {
                if (PlannedProduction <= 0)
                    return 0;
                return (double)ActualProduction / PlannedProduction * 100;
            }
        }

        // 完成率 显示文本
        public string CompletionRateDisplay => $"{CompletionRate:F1}%";

        public ICommand RefreshCommand { get; } // 刷新
        public ICommand SearchCommand { get; } // 查询
        public ICommand CopyCommand { get; } // 复制

        public ProductViewModel(UserModel userModel, ShellViewModel shellViewModel)
        {
            _currentUser = userModel;
            _shellViewModel = shellViewModel;

            // 初始化列表
            _recipeProcessSource = new List<string>();
            _processStatusSource = new List<string>();
            _workstationIdSource = new List<string>();

            // 初始化柱状图
            SeriesCollection = new SeriesCollection();
            LoadChartData();

            // 初始化筛选条件
            InitDatePickerAndComboBox();
            _ = InitProductListAsync();

            // 初始化产量统计
            //LoadProductionData(); 合并到 GetDataFromDBAsync() 里了

            RefreshCommand = new RelayCommand(ExecuteRefresh);
            SearchCommand = new RelayCommand(ExecuteSearch);
            CopyCommand = new RelayCommand<ProductModel>(ExecuteCopy);

            _shellViewModel.UserInfoUpdate += OnUserInfoUpdate;
        }

        #region 初始化柱状图
        private async void LoadChartData()
        {
            var dbData = await GetDataFromDBAsync();

            // 设置Y轴标签（日期）
            Labels = dbData.Select(y => y.Date).ToList();

            // 创建三个数据系列，分别对应三种状态
            SeriesCollection.Clear();

            // 正在加工 - 橙色 - ProcessingCount
            SeriesCollection.Add(new StackedRowSeries
            {
                Title = "正在加工",
                Values = new ChartValues<int>(dbData.Select(x => x.ProcessingCount)),
                DataLabels = true,
                FontSize = 20,
                Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#F3A270")),
                Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#C4602A")),
                StackMode = StackMode.Values, // 按值堆叠
            });

            // 加工完成 - 绿色 - CompletedCount
            SeriesCollection.Add(new StackedRowSeries
            {
                Title = "加工完成",
                Values = new ChartValues<int>(dbData.Select(x => x.CompletedCount)),
                DataLabels = true,
                FontSize = 20,
                Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8BB98D")),
                Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4A7C4D")),
                StackMode = StackMode.Values, // 按值堆叠
            });

            // 加工异常 - 红色 - AbnormalCount
            SeriesCollection.Add(new StackedRowSeries
            {
                Title = "加工异常",
                Values = new ChartValues<int>(dbData.Select(x => x.AbnormalCount)),
                DataLabels = true,
                FontSize = 20,
                //Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#E38A8B")),
                Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#D45A5A")),
                Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#9C2C2C")),
                StackMode = StackMode.Values, // 按值堆叠
            });
        }

        private async Task<List<ProductChartData>> GetDataFromDBAsync()
        {
            var result = new List<ProductChartData>();

            // 先获取最近一次加工数据的日期
            DateTime? latestDate = await GetLatestProcessDateAsync();

            // 如果没有数据，返回空列表
            if (!latestDate.HasValue)
                return result;

            Debug.WriteLine("最近一次加工数据的日期:" + latestDate);

            // 获取最近7天（包含最近日期）
            //var last7Days = Enumerable.Range(0, 7)
            //    .Select(i => latestDate.Value.AddDays(-i))
            //    .OrderBy(d => d)
            //    .ToList();

            // 直接根据SelectedDays生成对应的日期列表
            var dayCount = SelectedDays == 7 ? 7 : 14;
            var lastDays = Enumerable.Range(0, dayCount)
                .Select(i => latestDate.Value.AddDays(-i))
                .OrderBy(d => d)
                .ToList();

            // 用于计算总产量
            int totalPlanned = 0;
            int totalCompleted = 0;

            foreach (var date in lastDays)
            {
                string sql = @" SELECT 
                                COUNT(*) as TotalCount, 
                                COUNT(CASE WHEN process_status = 0 THEN 1 END) as ProcessingCount, 
                                COUNT(CASE WHEN process_status = 1 THEN 1 END) as CompletedCount, 
                                COUNT(CASE WHEN process_status = 2 THEN 1 END) as AbnormalCount 
                                FROM product_info 
                                WHERE DATE(start_time) = @Date";

                MySqlParameter parameters = new MySqlParameter("@Date", date.Date);

                var dbResult = await MysqlHelper.ExecuteQueryAsync(sql,
                    reader => new ProductChartData
                    {
                        Date = date.ToString("M/d"), // 格式: 1/15
                        TotalCount = reader["TotalCount"] != DBNull.Value ? Convert.ToInt32(reader["TotalCount"]) : 0,
                        ProcessingCount = reader["ProcessingCount"] != DBNull.Value ? Convert.ToInt32(reader["ProcessingCount"]) : 0,
                        CompletedCount = reader["CompletedCount"] != DBNull.Value ? Convert.ToInt32(reader["CompletedCount"]) : 0,
                        AbnormalCount = reader["AbnormalCount"] != DBNull.Value ? Convert.ToInt32(reader["AbnormalCount"]) : 0
                    },
                    parameters);

                var data = dbResult.FirstOrDefault() ?? new ProductChartData
                {
                    Date = date.ToString("M/d"),
                    TotalCount = 0,
                    ProcessingCount = 0,
                    CompletedCount = 0,
                    AbnormalCount = 0
                };

                result.Add(data);

                // 累加总产量
                totalPlanned += data.TotalCount;
                totalCompleted += data.CompletedCount;
            }
            // 更新产量数据
            PlannedProduction = totalPlanned;
            ActualProduction = totalCompleted;

            return result;
        }

        /// <summary>
        /// 从DB获取 最后一次加工记录的开始日期
        /// </summary>
        private async Task<DateTime?> GetLatestProcessDateAsync()
        {
            string sql = "SELECT MAX(DATE(start_time)) as LatestDate FROM product_info";

            //var result = await MysqlHelper.ExecuteQueryAsync(sql,
            //    reader => reader["LatestDate"] == DBNull.Value ? (DateTime?)null : Convert.ToDateTime(reader["LatestDate"]));

            var result = await MysqlHelper.ExecuteQueryAsync(sql,
                reader => reader.IsDBNull(0) ? null : (DateTime?)reader.GetDateTime(0));

            // 获取结果
            DateTime? latestDate = result.FirstOrDefault();

            return latestDate;
        }
        #endregion

        #region 操作
        /// <summary>
        /// 刷新
        /// </summary>
        private async void ExecuteRefresh(object obj) // async void 无法 try/catch 但可以用 RelayCommand 如果 async Task 要写异步版本的 RelayCommand 也就是 AsyncCommand
        {
            InitDatePickerAndComboBox(); // 初始化筛选条件
            await InitProductListAsync();

            // 清空现有数据
            SeriesCollection.Clear();
            Labels?.Clear();
            // 刷新柱状图
            LoadChartData();
        }

        /// <summary>
        /// 查询
        /// </summary>
        private async void ExecuteSearch(object obj)
        {
            await InitProductListAsync();
        }

        /// <summary>
        /// 复制
        /// </summary>
        private void ExecuteCopy(ProductModel product)
        {
            if (product == null)
                return;

            try
            {
                // 构建要复制的文本内容
                string productContent = FormatProductContent(product);

                // 复制到剪贴板
                Clipboard.SetText(productContent);

                // 显示成功消息
                MsgBoxHelper.Info("产品内容已复制到剪贴板");

                // 记录操作日志
                LogHelper.Info(this.GetType(), $"[复制产品]|" + $"复制产品记录 产品编号:{product.ProcessId}", _currentUser.UserAccount);
            }
            catch (Exception ex)
            {
                MsgBoxHelper.Error($"复制失败: {ex.Message}");
                LogHelper.Error(this.GetType(), "[复制产品]|" + "复制产品内容失败", ex, _currentUser.UserAccount);
            }
        }

        /// <summary>
        /// 格式化日志内容
        /// </summary>
        private string FormatProductContent(ProductModel product)
        {
            var aproduct = new StringBuilder();
            aproduct.AppendLine($"产品序列号: {product.ProductSN}");
            aproduct.AppendLine($"工艺流程: {product.RecipeProcessDisplay}");
            aproduct.AppendLine($"加工状态: {product.ProcessStatusDisplay}");
            aproduct.AppendLine($"开始时间: {product.StartTime:yyyy-MM-dd HH:mm:ss}");
            aproduct.AppendLine($"结束时间: {product.EndTime:yyyy-MM-dd HH:mm:ss}");
            aproduct.AppendLine($"加工时长: {product.ProcessTime}");
            aproduct.AppendLine($"工位: {product.WorkstationIdDisplay}");
            aproduct.AppendLine($"操作员: {product.Operator}");
            aproduct.AppendLine($"压力值: {product.PressureValue}");
            aproduct.AppendLine($"循环次数: {product.CycleCount}");
            return aproduct.ToString();
        }
        #endregion

        #region 显示
        private async Task InitProductListAsync()
        {
            // 防止重复加载
            if (IsProductListLoading)
                return;

            IsProductListLoading = true;

            try
            {
                var products = await Task.Run(() =>
                {
                    // SELECT* FROM product_info WHERE 1 = 1 AND start_time > '2023-10-21' AND end_time< '2025-10-21' AND recipe_process = 1 AND process_status = 1 AND workstation_id = 3 ORDER BY process_id DESC

                    List<MySqlParameter> parameters = new List<MySqlParameter>();

                    string sql = @"SELECT p.*, u.user_name 
                                    FROM product_info p 
                                    LEFT JOIN user_info u ON p.operator = u.user_account 
                                    WHERE 1 = 1";

                    // 界面显示值 → 数据库存储值
                    var recipeProcessMap = new Dictionary<string, int>
                    {
                        { "流程1", 1 },  // 界面显示"流程1"，数据库存1
                        { "流程2", 2 }   // 界面显示"流程2"，数据库存2
                    };
                    var processStatusMap = new Dictionary<string, int>
                    {
                        { "正在加工", 0 },
                        { "加工完成", 1 },
                        { "加工异常", 2 }
                    };
                    var workstationIdMap = new Dictionary<string, int>
                    {
                        { "工位1", 1 },
                        { "工位2", 2 },
                        { "工位3", 3 },
                        { "工位4", 4 },
                        { "工位5", 5 },
                        { "工位6", 6 }
                    };

                    // 时间查询
                    if (StartTime != null)
                    {
                        sql += " AND start_time > @StartTime";
                        parameters.Add(new MySqlParameter("@StartTime", StartTime.Value.Date)); // 只取日期部分
                    }
                    if (EndTime != null)
                    {
                        sql += " AND end_time < @EndTime";
                        parameters.Add(new MySqlParameter("@EndTime", EndTime.Value.Date.AddDays(1))); // 结束日期的下一天
                    }

                    // ComboBox
                    if (!string.IsNullOrEmpty(SelectedRecipeProcess))
                    {
                        int dbRecipeProcess = recipeProcessMap[SelectedRecipeProcess]; // 界面显示值 → 数据库存储值
                        sql += " AND recipe_process = @RecipeProcess";
                        parameters.Add(new MySqlParameter("@RecipeProcess", dbRecipeProcess));
                    }
                    if (!string.IsNullOrEmpty(SelectedProcessStatus))
                    {
                        int dbProcessStatus = processStatusMap[SelectedProcessStatus]; // 界面显示值 → 数据库存储值
                        sql += " AND process_status = @ProcessStatus";
                        parameters.Add(new MySqlParameter("@ProcessStatus", dbProcessStatus));
                    }
                    if (!string.IsNullOrEmpty(SelectedWorkstationId))
                    {
                        int dbWorkstationId = workstationIdMap[SelectedWorkstationId]; // 界面显示值 → 数据库存储值
                        sql += " AND workstation_id = @WorkstationId";
                        parameters.Add(new MySqlParameter("@WorkstationId", dbWorkstationId));
                    }

                    // 模糊搜索 开销大 放后面
                    if (!string.IsNullOrEmpty(TxtSearch))
                    {
                        sql += " AND product_sn like @ProductSN";
                        parameters.Add(new MySqlParameter("@ProductSN", MySqlDbType.VarChar) { Value = "%" + TxtSearch + "%" });
                    }

                    // 降序
                    sql += " ORDER BY process_id DESC";


                    Func<IDataRecord, ProductModel> mapper = reader => new ProductModel
                    {
                        ProcessId = reader["process_id"] == DBNull.Value ? 0 : Convert.ToInt32(reader["process_id"]),
                        ProductSN = reader["product_sn"] == DBNull.Value ? string.Empty : reader["product_sn"].ToString(),
                        StartTime = reader["start_time"] == DBNull.Value ? (DateTime?)null : Convert.ToDateTime(reader["start_time"]),
                        EndTime = reader["end_time"] == DBNull.Value ? (DateTime?)null : Convert.ToDateTime(reader["end_time"]),
                        ProcessTime = reader["process_time"] == DBNull.Value ? (TimeSpan?)null : TimeSpan.Parse(reader["process_time"].ToString()),
                        RecipeProcess = reader["recipe_process"] == DBNull.Value ? 0 : Convert.ToInt32(reader["recipe_process"]),
                        CycleCount = reader["cycle_count"] == DBNull.Value ? 0 : Convert.ToInt32(reader["cycle_count"]),
                        PressureValue = reader["pressure_value"] == DBNull.Value ? string.Empty : reader["pressure_value"].ToString(),
                        WorkstationId = reader["workstation_id"] == DBNull.Value ? 0 : Convert.ToInt32(reader["workstation_id"]),
                        Operator = reader["user_name"] == DBNull.Value ? string.Empty : reader["user_name"].ToString(),
                        ProcessStatus = reader["process_status"] == DBNull.Value ? 0 : Convert.ToInt32(reader["process_status"])
                    };

                    return MysqlHelper.ExecuteQuery<ProductModel>(sql, mapper, parameters.ToArray());
                });

                ProductList = products;
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), "[加载产品]|" + "产品列表加载失败", ex, _currentUser.UserAccount);
                ProductList = new List<ProductModel>();
            }
            finally
            {
                IsProductListLoading = false;
            }
        }
        #endregion

        #region 初始化
        /// <summary>
        /// 初始化筛选条件
        /// </summary>
        private void InitDatePickerAndComboBox()
        {
            StartTime = null;
            EndTime = null;

            TxtSearch = null;

            RecipeProcessSource?.Clear();
            RecipeProcessSource.Add("流程1");
            RecipeProcessSource.Add("流程2");
            SelectedRecipeProcess = null;

            ProcessStatusSource?.Clear();
            ProcessStatusSource.Add("正在加工");
            ProcessStatusSource.Add("加工完成");
            ProcessStatusSource.Add("加工异常");
            SelectedProcessStatus = null;

            WorkstationIdSource?.Clear();
            WorkstationIdSource.Add("工位1");
            WorkstationIdSource.Add("工位2");
            WorkstationIdSource.Add("工位3");
            WorkstationIdSource.Add("工位4");
            WorkstationIdSource.Add("工位5");
            WorkstationIdSource.Add("工位6");
            SelectedWorkstationId = null;
        }
        #endregion

        #region 更新当前登录用户的信息 事件处理
        /// <summary>
        /// 接收到通知
        /// </summary>
        private void OnUserInfoUpdate(object sender, UserInfoUpdateEventArgs e)
        {
            // 空值检查，避免NullReferenceException
            if (e?.UpdatedUser != null)
            {
                _currentUser = e.UpdatedUser;
                Debug.WriteLine("Product页面|用户信息已更新");
            }
            else
            {
                Debug.WriteLine("收到空的事件参数");
            }
        }

        /// <summary>
        /// 析构函数中的事件取消订阅
        /// </summary>
        ~ProductViewModel()
        {
            _shellViewModel.UserInfoUpdate -= OnUserInfoUpdate;
        }
        #endregion

    }
}
